<?Lassoscript
// Last modified 9/6/11 by ECL, Landmann InterActive

// CHANGE NOTES
// 9/6/11 ECL
// Complete rewrite to fix longstanding problem with multiple heirarchy levels generating invalid HTML

// Debugging
Var('svDebug' = 'N');

// Used to hold the HTML - Used for debugging only
Var('DebugComments' = string);

// Used to hold the dropdown Javascript
Var('DropdownJS' = string);

// Used to hold the dropdown HTML
Var('DropdownHTML' = string);

// Used to hold an array of all the links in the site
// The array contains an indention level used for building unordered lists, a delimiter (|||), URL path, delimiter, and the headline
// Level 0 = root level
// SAMPLE DATA -- See siteconfig for various arrays and maps
/*
SitemapArray = array( (0|||/our-coffees|||Our Coffees)
( 1|||/our-coffees/steep-&-brew-coffees|||Steep & Brew Coffees)
( 1|||/our-coffees/cafe-fair-coffees|||Café Fair Coffees)
( 1|||/our-coffees/coffees-for-every-occasion|||Coffees for Every Occasion)
( 1|||/our-coffees/buy-coffee-online|||Buy Coffee Online)
( 0|||/coffee-for-business|||Coffee for Business)
( 0|||/organic-/-fair-trade|||Organic / Fair Trade)
( 1|||/organic-/-fair-trade/about-cafe-fair|||About Cafe Fair)
( 1|||/organic-/-fair-trade/about-cafe-fair-coffees|||About Cafe Fair Coffees)
( 0|||/community|||Community)
( 0|||/cafes|||Cafes)
( 1|||/cafes/we-inspire-cafe-owners-to-achieve-success|||We Inspire Cafe Owners to Achieve Success)
( 1|||/cafes/referrals-from-cafe-owners|||Referrals from Cafe Owners)
( 1|||/cafes/licensee-cafes|||Licensee Cafes)
( 2|||/cafes/licensee-cafes/licensee-cafes|||Licensee Cafes)
( 1|||/cafes/steep-&-brew-cafes|||Steep & Brew Cafes)
( 2|||/cafes/steep-&-brew-cafes/cafe-business|||Cafe Business)
( 0|||/contact-us|||Contact Us)
*/
Var('SitemapArray' = array);

// Control var used to determine whether we are in a root level
Var('InsideUL' = false);

// Used for the final link in the URL
Var('LinkContentPath' = string);

// Used to hold the previous heirarchy path, used to build the URL
Var('PrevLevel' = string);

// Used to determine the level of indention in the navigation
// This will be processed to create the unordered list
Var('ThisNavDepth' = integer);

// Used to store a dynamically-named var to determine which UL level we are in and whether it is closed
Var('ULHeirMap' = map);

// Used to increment the HTML ID (e.g. <li id="RootNav4">
Var('HTMLIDCounter' = integer);

// Check to see if client-specific stylesheet exists named jqueryslidemenu2.css. If it does not, use jqueryslidemenu.css.
Var('ClientStylesheetExists' = File_Exists(($svCSSPath+'jqueryslidemenu2.css')));

// Use this code for Dynamic Drive-style jQuery slider ("css flyout") menus
$DropdownJS = ('\t<link rel="stylesheet" type="text/css" href="'+($svCSSPath));

// Include stock jqueryslidemenu.css if $GalleryContent is defined to load the default Gallery stylesheet.
// Otherwise include jqueryslidemenu2.css as that is the client-specific stylesheet.
// Checking for a value of 0 because that is the default
If(Var('vGalleryGroupID') != 0);
	$DropdownJS += 'jqueryslidemenu.css';
Else;
	If($ClientStylesheetExists == true);
		Var('UseThisStylesheet' = 'jqueryslidemenu2.css');
	Else;
		Var('UseThisStylesheet' = 'jqueryslidemenu.css');
	/If;
	$DropdownJS += $UseThisStylesheet;
/If;
$DropdownJS += ('">
	<!--[if lte IE 7]>
		<style type="text/css">
			html .jqueryslidemenu{height: 1%;} /*Holly Hack for IE7 and below*/
		</style>
	<![endif]-->\n');

// Include alternate JS if $GalleryContent is defined.
// This is done solely for the purpose of controlling the down and right arrows.
If(Var('vGalleryGroupID') != 0);
	$DropdownJS += ('\t<script type="text/javascript" src="'+($svJSPath)+'jqueryslidemenu2.js"></script>\n');
Else;
	$DropdownJS += ('\t<script type="text/javascript" src="'+($svJSPath)+'jqueryslidemenu.js"></script>\n');
/If;

// START container for left navbar
$DropdownHTML += ('<!-- START build_dropdown -->\n');
$DropdownHTML += ('<!-- vGalleryGroupID = '+(Var('vGalleryGroupID'))+'-->\n');
$DropdownHTML += ('<div id="myslidemenu" class="jqueryslidemenu">\n');
$DropdownHTML += ('\t<ul>\n\t\t');

// Get the entire navigation heirarchy (Active nodes only)
Var('SQLSelectFullNode' = ('/* Select full node */
	SELECT node.id, node.name, node.HeirarchySlug,
	(COUNT(parent.name) - 1) AS depth
	FROM '+($svHeirarchyTable)+' AS node, '+($svHeirarchyTable)+' AS parent
	WHERE node.lft BETWEEN parent.lft AND parent.rgt
	AND node.Active = "Y"
	GROUP BY node.id
	ORDER BY node.lft'));

Inline($IV_Heirarchy, -SQL=$SQLSelectFullNode, -Table=$svHeirarchyTable);

// If($svDebug == 'Y');
	//	$DebugComments += ('<p class="debug">\n');
//		$DebugComments += ('<strong>Found_Count = </strong>'+(Found_Count)+'<br>\n');
//		$DebugComments += ('<strong>Error_CurrentError = </strong>'+(Error_CurrentError)+'<br>\n');
	//		$DebugComments += ('<strong>SQLSelectFullNode = </strong>'+($SQLSelectFullNode)+'<br>\n');
	//		$DebugComments += ('<strong>URLLabelMap = </strong>'+($URLLabelMap)+'<br>\n');
//		$DebugComments += ('<strong>ContentIDMap = </strong>'+($ContentIDMap)+'<br>\n');
//		$DebugComments += ('<strong>Records_Array = </strong>'+(Records_Array)+'<br>\n');
	//	Var('ContentIDMapClean' = String_Replace(($ContentIDMap),-find='), (',-replace=')<br>(\n'));
	//	$DebugComments += ('<strong>ContentHeadMap = </strong>'+($ContentHeadMap)+'<br>\n');
	//	$DebugComments += ('<strong>ContentPathMap = </strong>'+($ContentPathMap)+'<br>\n');
	//	$DebugComments += ('<strong>ContentIDMapClean = </strong>'+($ContentIDMapClean)+'<br>\n');
	//	$DebugComments += ('<strong>ContentHeirIDMap = </strong>'+($ContentHeirIDMap)+'<br>\n');
	//	$DebugComments += ('</p>\n');
//	/If;

	Var('IndentLevel' = 0);

	Records;

		Var('ThisHeirarchyID' = Field('id'),
			'ThisDepth' = Integer(Field('depth')),
			'ThisHeirarchyName' = Field('name'),
			'ThisNodeNameSlug' = Field('HeirarchySlug'),
			'MyItemURLPath' = string);

		// LOOK AHEAD for content pages
		// Set to true when ths Heirarchy level has content pages
		Local('HasContent' = boolean);		
		Var('MyItemID' = ($ContentHeirIDMap->find($ThisHeirarchyID)));
		// Used to see if there is more than one content page for this Heirarchy ID
		// If there is more than one page, the array size will be > 1
		Var('MyItemSize' = $MyItemID->size);
		
		// Set #HasContent to true if this Hierarchy ID has content
		Local('HasContent' = (Var('MyItemID') != '') ? true | false);
		
		// Manufacture the links
		If(#HasContent == true);

			// Assign ThisDepth to ThisNavDepth
			$ThisNavDepth = $ThisDepth;

			// Always make the link the Heirarchy Name for Depth 0 menu items
			If(($MyItemSize == 1) && ($ThisDepth == 0));
				// Clean the URLSlug - Replace spaces with dashes
				// Note: Path has been modified by prefixing tthe heirarchy name
				If($PrevLevel == $ThisNodeNameSlug);
					If(Loop_Count == 1);
						Local('out' = $ThisNodeNameSlug);
					Else;
						Local('out' = (($PrevLevel)+'/'+($ThisNodeNameSlug)));
					/If;
				Else;
					Local('out' = $ThisNodeNameSlug);
				/If;
				#out->replace(' ','-');
				$LinkContentPath = (String_LowerCase(#out));

				// Add leading slash for root level links
				// WATCH IT - Modifies $LinkContentPath IN PLACE
				If(!($LinkContentPath->BeginsWith('/')));
					Var('LinkContentPath' = (('/')+$LinkContentPath));
				/If;
				// Used to look up the Content ID
				Var('LookupThisLink' = $LinkContentPath);
				
				// Insert the page into the array
//				$DebugComments += ('<!-- 114: LinkContentPath = '+($LinkContentPath ' -->\n';
//				$DebugComments += ('<strong>114 ThisHeirarchyName = </strong>'+($ThisHeirarchyName ' <br>\n';
				$SitemapArray->insert(($ThisNavDepth)+'|||'+($LinkContentPath)+'|||'+($ThisHeirarchyName));

				$InsideUL = false;
		
				// Set the previous level
				$PrevLevel = $ThisHeirarchyName;

			Else;

				// Clean the URLSlug - Replace spaces with dashes
				// Path has been modified by prefixing the heirarchy name
				If($ThisDepth > 0);
					If(Loop_Count == 1);
						Local('out' = $ThisNodeNameSlug);
					Else;
						Local('out' = (($PrevLevel)+'/'+($ThisNodeNameSlug)));
					/If;
				Else;
					Local('out' = $ThisNodeNameSlug);
				/If;

				#out->replace(' ','-');
				$LinkContentPath = (String_LowerCase(#out));

				// Add leading slash for root level links
				// WATCH IT - Modifies $LinkContentPath IN PLACE
				If(!($LinkContentPath->BeginsWith('/')));
					Var('LinkContentPath' = (('/')+$LinkContentPath));
				/If;
				// Used to look up the Content ID
				Var('LookupThisLink' = $LinkContentPath);
				
				// Insert the page into the array
				// Add leading slash for root level links
				If(!($LinkContentPath->BeginsWith('/')));
					Var('LookupThisLink' = (('/')+$LinkContentPath));
					Else;
					Var('LookupThisLink' = $LinkContentPath);
					/If;
				// At a nav level (not a content page), so we need to use the $ThisHeirarchyName
//				$DebugComments += ('<strong>160 ThisHeirarchyName = </strong>'+($ThisHeirarchyName ' <br>\n';
				$SitemapArray->insert(($ThisNavDepth)+'|||'+($LinkContentPath)+'|||'+($ThisHeirarchyName));

					$InsideUL = true;

				// Increment ThisNavDepth because now we're going deeper
				$ThisNavDepth = Math_Add($ThisNavDepth, 1);

				Iterate($MyItemID, Local('i'));
					Var('MyItemLabel' = ($ContentHeadMap->find(#i)));
					Var('MyItemURLPath' = ($ContentPathMap->find(#i)));
					// Used to look up the Content ID
					Var('LookupThisLink' = $MyItemURLPath);
						// Clean the URLSlug - Replace spaces with dashes
					Local('out' = $MyItemURLPath);
						#out->replace(' ','-');
					$LinkContentPath = (String_LowerCase(#out));

					// Insert the page into the array
					// We are at the content level, so use $MyItemLabel
					$SitemapArray->insert(($ThisNavDepth)+'|||'+($LinkContentPath)+'|||'+($MyItemLabel));

					// Reset the previous level head - DO NOT MOVE
					If(Loop_Count != 1);
						Var('PrevLevel' = $ThisHeirarchyName);
						/If;

					/Iterate;

			/If;

		/If;

		// Reset $InsideUL
		If(($ThisDepth != 0) && ($InsideUL == true));
			$InsideUL = false;
				/If;

		$InsideUL = false;

		If($ThisDepth > $IndentLevel);
			$IndentLevel = $IndentLevel + 1;
		Else($ThisDepth < $IndentLevel);
			$IndentLevel = $IndentLevel - 1;
		Else($ThisDepth == $IndentLevel);
			// No change to level
			/If;

	/Records;

/Inline;

// Debug;
//	Var('SitemapArrayClean' = String_Replace(($SitemapArray),-find='), (',-replace=')<br>(\n'));
//	('<strong>SitemapArray = </strong>'+($SitemapArrayClean)+'<br>\n');
//	('<strong>230 SitemapArray</strong> = '+($SitemapArray)+'<br>\n');
//	('<strong>230 SitemapArray size </strong> = '+($SitemapArray->size)+'<br>\n');
//	('<strong>230 DebugComments</strong> = '+($DebugComments)+'<br>\n');
// /Debug;

// Start off with $IndentLevel = 0
$IndentLevel = 0;

// Used to capture the previous level for comparison to the present level
Var('PrevLevelInt' = 0);

Iterate($SitemapArray, Local('i'));

	// THIS ELEMENT's INFO
	Var('ThisElementSplit' = #i->split('|||'));
	Var('ThisLevel' = ($ThisElementSplit->Get('1')));
	Var('ThisElement' = ($ThisElementSplit->Get('2')));
	Var('ThisElementName' = ($ThisElementSplit->Get('3')));

	/**********************************************************/
	// LOOK AHEAD for next level - Used to determine whether we need to close a UL or LI
	/**********************************************************/
	// NEXT ELEMENT's level
	Var('NextLoopCount' = Math_Add(LoopCount,1));

	Protect;
		Var('NextLevel' = (Integer($SitemapArray->get($NextLoopCount)->split('|||')->Get('1'))));
	/Protect;

//	('\n<!-- ThisLevel = '+($ThisLevel)+' - '+($ThisElement)+' -->\n');
//	('<!-- NextLoopCount = '+($NextLoopCount)+' -->\n');
//	('<!-- NextLevel = '+($NextLevel)+' -->\n');

	/**********************************************************/
	// Process this level
	/**********************************************************/
	// Reverse lookup of the path to get the content ID
	Var('Temp1' = $URLLabelMap->find($ThisElement));
	// Now that we have the content ID, go get the content head
	Var('MyItemLabel' = $ContentHeadMap->find($Temp1));

	// Increment the HTMLIDCounter
	If($ThisLevel == 0);
		$HTMLIDCounter = Math_Add($HTMLIDCounter,1);
	/If;

	If($ThisLevel > $PrevLevelInt);
// WORKS $DropdownHTML += ('\n\t\t\t<ul>\n\t\t\t\t<li>');
		$DropdownHTML += ('\n');
		Var('InsideUlVarName' = ('InsideUL'+$ThisLevel));
		$ULHeirMap->insert($InsideUlVarName = true);
//		$DropdownHTML += ('<!-- UL LEVEL: '+($InsideUlVarName)+' = '+($ULHeirMap->find($InsideUlVarName))+' -->\n');
				Loop(-from=1, -to=(Math_Add($ThisLevel,2))); $DropdownHTML += '\t'; /Loop;
//		$DropdownHTML += ('<!-- 1a -->');
		$DropdownHTML += ('<ul>\n');
		// Level 0
			Loop(-from=1, -to=(Math_Add($ThisLevel,3))); $DropdownHTML += '\t'; /Loop;
//		$DropdownHTML += ('<!-- 1b -->');
		$DropdownHTML += ('<li');
		If($ThisLevel == 0);
			$DropdownHTML += (' id="RootNav'+($HTMLIDCounter)+'"');
		/If;
		$DropdownHTML += ('>');

	// Next item is shallower
	Else($ThisLevel < $PrevLevelInt);

//		$DropdownHTML += ('-- 2b ThisLevel LESS THAN PrevLevelInt, Output /li /ul li<br>\n');
// WORKS	$DropdownHTML += ('</li>\n\t\t\t</ul>\n\t\t</li>\n\t\t<li>');
//		$DropdownHTML += ('<!-- 2 -->');
		$DropdownHTML += ('</li>\n');

		// Check the difference between levels & output accordingly
		Var('LevelDiffCheck' = Math_Sub($NextLevel,$ThisLevel));

		// Check the difference between levels & output accordingly
		Var('LevelDiffCheckNext' = Math_Sub($NextLevel,$ThisLevel));
		Var('LevelDiffCheckPrev' = Math_Sub($PrevLevelInt,$ThisLevel));
//		$DropdownHTML += ('LevelDiffCheck $ThisLevel = '+($ThisLevel)+'\n');
//		$DropdownHTML += ('LevelDiffCheck $NextLevel = '+($NextLevel)+'\n');
//		$DropdownHTML += ('LevelDiffCheck = '+($LevelDiffCheck)+'\n');
//		$DropdownHTML += ('LevelDiffCheckNext = '+($LevelDiffCheckNext)+'\n');
//		$DropdownHTML += ('LevelDiffCheckPrev = '+($LevelDiffCheckPrev)+'\n');
		Protect;
			If($ULHeirMap->find('InsideUL1'));
//				$DropdownHTML += ('</ul></li><!-- InsideUL1 310-->\n');
//				$DropdownHTML += ('<!-- Protect 1-->\n');
					Loop(-from=1, -to=(Math_Add($ThisLevel,3))); $DropdownHTML += '\t'; /Loop;
				$DropdownHTML += ('</ul>\n');
//				$DropdownHTML += ('<!-- Protect 2-->\n');
					Loop(-from=1, -to=(Math_Add($ThisLevel,2))); $DropdownHTML += '\t'; /Loop;
				$DropdownHTML += ('</li>\n');
				$ULHeirMap->remove('InsideUL1');
			/If;
		/Protect;

		If($LevelDiffCheckNext > 0); 
			Loop(-from=1, -to=$LevelDiffCheckNext); $DropdownHTML += ('</ul><ul><!-- InsideUL2 310a-->\n'); /Loop;
			$ULHeirMap->remove('InsideUL2');
		Else($LevelDiffCheckPrev > 1);
			$DropdownHTML += ('</ul></li></ul></li><!-- InsideUL2 310b-->\n');
			$ULHeirMap->remove('InsideUL2');
		Else(($LevelDiffCheckPrev == 0) && ($LevelDiffCheckNext == 0));
//			$DropdownHTML += ('<!-- Output Nothing - InsideUL2 310c-->\n');
			$DropdownHTML += ('<!-- -->\n');
		Else;
//			$DropdownHTML += ('<!-- Output Nothing - InsideUL2 310d-->\n');
			$DropdownHTML += ('<!-- -->\n');
			$ULHeirMap->remove('InsideUL2');
		/If;

		Loop(-from=1, -to=(Math_Add($ThisLevel,2))); $DropdownHTML += '\t'; /Loop;
//		$DropdownHTML += ('<!-- 3 -->');
		$DropdownHTML += ('<li');
		// Output HTML ID for Root Levels
		If($ThisLevel == 0);
			$DropdownHTML += (' id="RootNav'+($HTMLIDCounter)+'"');
		/If;
		$DropdownHTML += ('>');

	Else($ThisLevel == $PrevLevelInt);

		If(Loop_Count > 1);
// 			$DropdownHTML += ('-- 2c ThisLevel SAME AS PrevLevelInt, Output li<br>\n');
// WORKS	$DropdownHTML += ('</li>\n\t\t<li>');
//			$DropdownHTML += ('<!-- 4 -->');
			$DropdownHTML += ('</li>\n');
				Loop(-from=1, -to=(Math_Add($ThisLevel,2))); $DropdownHTML += '\t'; /Loop;
//			$DropdownHTML += ('<!-- 5 -->');
		/If;
			$DropdownHTML += ('<li');
			// Output HTML ID for Root Levels
			If($ThisLevel == 0);
				$DropdownHTML += (' id="RootNav'+($HTMLIDCounter)+'"');
			/If;
			$DropdownHTML += ('>');
	/If;

//	(($DropdownHTML)+'<a href="'+($ThisElement)+'">'+($ThisElementName)+'</a>');
	$DropdownHTML += ('<a href="'+($ThisElement)+'">'+($ThisElementName)+'</a>');

	// Set the Previous Level for checking next time around
	$PrevLevelInt = $ThisLevel;
//	('AT END PrevLevelInt = '+($PrevLevelInt)+'<br>\n');

/Iterate;

// END container
$DropdownHTML += ('		</li>
	</ul>
	<br style="clear: left">
</div>\n');
$DropdownHTML += ('<!-- END build_dropdown -->\n');

// Uncomment to see DebugComments
// Output($DebugComments, -EncodeNone);

?>
